#include "cs.h"
void cohen_sutherlan(Polygon<val_t> &region, Line<val_t> &line)
{
    log("Line : (%d,%d)->(%d,%d)\n", line.start.x, line.start.y, line.end.x, line.end.y);
    // getchar();
    Line<val_t> ret = line;
    code_t code1, code2;
    code1 = get_code(region, line.start);
    code2 = get_code(region, line.end);
    log("code1 = %x,code2 = %x \n", code1, code2);
    if ((code1 | code2) == 0)
    {
        // DRAW HERE;
        log("draw!\n", "");
        ret.draw();
        return;
    }
    else if (code1 & code2)
    {
        //DON'T DRAW
        log("don't draw !\n");
        return;
    }
    // bool outside_is_start = code1!=0;
    if (code1 == 0)
    {
        // start点在矩形框内,交换start end 更新code
        // Point<val_t> p = line.start;
        ret.start = line.end;
        ret.end = line.start;
        ret.update_edges();
    }
    log("GOT RET (%d,%d)->(%d,%d) \n", ret.start.x, ret.start.y, ret.end.x, ret.end.y);
    code1 = get_code(region, ret.start);
    code2 = get_code(region, ret.end);

    int i = 0;
    for (i = 0; i < 4; i++)
        if (code1 & (1 << i))
            break;

    // Line<val_t> edge;
    Point<val_t> cross_point;
    switch (i)
    {
    // 左边界相交
    case 0:
        // edge = Line<val_t>({region.left, region.bottom}, {region.left, region.top});
        // edge.update_edges();
        cross_point = ret.get_point_at_x(region.left);
        break;
    // 右边界相交
    case 1:
        // edge = Line<val_t>({region.right, region.bottom}, {region.right, region.top});
        // edge.update_edges();
        cross_point = ret.get_point_at_x(region.right);
        break;
    // 下边界相交
    case 2:
        // edge = Line<val_t>({region.left, region.bottom}, {region.right, region.bottom});
        // edge.update_edges();
        cross_point = ret.get_point_at_y(region.bottom);
        break;
    // 上边界相交
    case 3:
        // edge = Line<val_t>({region.left, region.top}, {region.right, region.top});
        // edge.update_edges();
        cross_point = ret.get_point_at_y(region.top);
        break;
    default:
        log("点未与边界相交!\n");
        exit(-1);
        break;
    }
    ret.start = cross_point;
    ret.update_edges();

    return cohen_sutherlan(region, ret);
}
code_t get_code(Polygon<val_t> &region, Point<val_t> &point)
{
    code_t code = 0;
    log("[region] l=%g, r=%g, b=%g, t=%g \n", (double)region.left, (double)region.right, (double)region.bottom, (double)region.top);
    code |= (point.x < region.left ? 1 : 0);
    code |= (point.x > region.right ? 1 : 0) << 1;
    code |= (point.y < region.bottom ? 1 : 0) << 2;
    code |= (point.y > region.top ? 1 : 0) << 3;
    log("code = %d\n", code);
    return code;
}
